package com.weifly.weistock.optionvix.impl;

import com.weifly.weistock.core.util.visitor.PreviousVisitor;
import com.weifly.weistock.optionvix.OptionVixConfigService;
import com.weifly.weistock.optionvix.OptionVixConverter;
import com.weifly.weistock.optionvix.OptionVixMonitorService;
import com.weifly.weistock.optionvix.bo.VixDayBO;
import com.weifly.weistock.optionvix.bo.VixDayExternalBO;
import com.weifly.weistock.optionvix.bo.VixYearBO;
import com.weifly.weistock.optionvix.dto.GetDayListRequest;
import com.weifly.weistock.optionvix.dto.VixSummaryDTO;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * VIX监控服务
 *
 * @author weifly
 * @since 2021/1/21
 */
public class OptionVixMonitorServiceImpl implements OptionVixMonitorService {

    private SortedMap<String, VixYearBO> yearMap = new TreeMap<>(); // key有序的map
    private Map<String, VixDayExternalBO> dayExternalMap; // VIX附加信息集合

    private OptionVixConfigService optionVixConfigService;

    public void setOptionVixConfigService(OptionVixConfigService optionVixConfigService) {
        this.optionVixConfigService = optionVixConfigService;
    }

    @Override
    public void updateYearList(List<VixYearBO> yearList) {
        this.yearMap.clear();
        for (VixYearBO vixYear : yearList) {
            this.yearMap.put(vixYear.getYear(), vixYear);
        }
        this.dayExternalMap = new VixDayExternalCalculator(this.yearMap.values()).calc();
    }

    @Override
    public void updateVix(VixDayBO vixDay) {
        // 合并day到year
        String year = vixDay.getDay().substring(0, 4);
        VixYearBO vixYear = this.yearMap.get(year);
        if (vixYear == null) {
            vixYear = new VixYearBO();
            vixYear.setYear(year);
            this.yearMap.put(year, vixYear);
        }
        OptionVixConverter.updateDayOfYear(vixYear, vixDay);

        // 写入存储
        this.optionVixConfigService.saveYear(vixYear);

        // 更新VIX附加信息
        this.dayExternalMap = new VixDayExternalCalculator(this.yearMap.values()).calc();
        this.optionVixConfigService.saveDayExternal(this.dayExternalMap);
    }

    @Override
    public VixSummaryDTO calcMonitorInfo() {
        return new VixSummaryCalculator(this.yearMap.values()).calc();
    }

    @Override
    public List<VixDayBO> getVixDayList(GetDayListRequest dayListRequest) {
        List<VixDayBO> dayList = new ArrayList<>();
        Iterator<VixDayBO> dayIter = new PreviousVisitor(this.yearMap.values());
        while (dayIter.hasNext()) {
            VixDayBO vixDay = dayIter.next();
            if (StringUtils.isBlank(dayListRequest.getDay()) || dayListRequest.getDay().compareTo(vixDay.getDay()) > 0) {
                dayList.add(vixDay);
                if (dayList.size() >= dayListRequest.getLimit()) {
                    break;
                }
            }
        }
        return dayList;
    }

    @Override
    public VixDayExternalBO getVixDayExternal(String day) {
        return this.dayExternalMap.get(day);
    }

    @Override
    public List<VixDayBO> loadChartDayList(String lowDay) {
        LinkedList<VixDayBO> dayList = new LinkedList<>();
        if (StringUtils.isBlank(lowDay)) {
            return dayList;
        }

        Iterator<VixDayBO> dayIter = new PreviousVisitor(this.yearMap.values());
        while (dayIter.hasNext()) {
            VixDayBO vixDay = dayIter.next();
            if (lowDay.compareTo(vixDay.getDay()) > 0) {
                break;
            } else {
                dayList.addFirst(vixDay);
            }
        }
        return dayList;
    }
}
